#include "TableViewWithLoader.h"
#include <QHeaderView>
#include <QScrollBar>

/**
 * @brief 构造函数
 * @param parent 父窗口
 */
TableViewWithLoader::TableViewWithLoader(QWidget *parent)
    : QTableView(parent)
{
    // 初始化可见行向量
    m_visibleRows.resize(0);
}

/**
 * @brief 设置模型
 * @param model 数据模型
 */
void TableViewWithLoader::setModel(QAbstractItemModel *model)
{
    QTableView::setModel(model);

    // 重置可见行向量
    if (model) {
        m_visibleRows.resize(model->rowCount());
        m_visibleRows.fill(false);
    } else {
        m_visibleRows.resize(0);
    }

    // 初始更新可见区域
    updateVisibleArea();
}

/**
 * @brief 重写滚动内容方法
 * @param dx X方向滚动距离
 * @param dy Y方向滚动距离
 */
void TableViewWithLoader::scrollContentsBy(int dx, int dy)
{
    // 调用基类实现
    QTableView::scrollContentsBy(dx, dy);

    // 更新可见区域
    updateVisibleArea();
}

/**
 * @brief 更新可见区域
 * 检测可见行范围并发出信号通知模型
 */
void TableViewWithLoader::updateVisibleArea()
{
    if (!model()) return;

    // 获取可见区域的行范围
    int firstVisibleRow = rowAt(0);
    int lastVisibleRow = rowAt(viewport()->height() - 1);

    // 边界检查
    firstVisibleRow = qMax(0, firstVisibleRow);
    lastVisibleRow = qMin(model()->rowCount() - 1, lastVisibleRow);

    // 确保可见行向量大小正确
    if (m_visibleRows.size() != model()->rowCount()) {
        m_visibleRows.resize(model()->rowCount());
        m_visibleRows.fill(false);
    }

    // 标记可见行
    bool rangeChanged = false;
    for (int i = firstVisibleRow; i <= lastVisibleRow; ++i) {
        if (!m_visibleRows[i]) {
            m_visibleRows[i] = true;
            rangeChanged = true;
        }
    }

    // 检查是否有行变为不可见
    for (int i = 0; i < m_visibleRows.size(); ++i) {
        if (m_visibleRows[i] && (i < firstVisibleRow || i > lastVisibleRow)) {
            m_visibleRows[i] = false;
            rangeChanged = true;
        }
    }

    // 如果可见范围发生变化，发出信号
    if (rangeChanged) {
        emit visibleRangeChanged(firstVisibleRow, lastVisibleRow);
    }
}
